/// -----------------------------------------------------------------------------------------------------------
/// Module      :  QueueStorageAdapterConnectionUri.cs
/// Description :  This is the class for representing an adapter connection uri
/// -----------------------------------------------------------------------------------------------------------

#region Using Directives

using System;
using System.Text;

using Microsoft.ServiceModel.Channels.Common;

#endregion

namespace BizTalkFactory.Adapters.AzureStorage
{
    /// <summary>
    /// This is the class for building the QueueStorageAdapterConnectionUri
    /// </summary>
    public sealed class AzureStorageAdapterConnectionUri : ConnectionUri
    {
        #region Constants

        public const String DevelopmentStorageAccountName = "devstoreaccount1";
        public const String DevelopmentStorageAccountkey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";

        #endregion Constants

        #region Private Members

        private string path_ = String.Empty;

        #endregion Private Members

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the ConnectionUri class
        /// </summary>
        public AzureStorageAdapterConnectionUri()
        {
            this.Uri = new Uri(SampleUriString);
        }

        /// <summary>
        /// Initializes a new instance of the ConnectionUri class with a Uri object
        /// </summary>
        public AzureStorageAdapterConnectionUri(Uri uri)
            : base()
        {
            Uri = uri;
        }

        #endregion Constructors

        #region Custom Generated Properties

        [System.ComponentModel.Category("Development Storage")]
        //[Microsoft.ServiceModel.Channels.BindingPropertyDirection(true,true)]
        public bool UseDevelopmentStorage { get; set; }

        [System.ComponentModel.Category("Account Information")]
        public string AccountName { get; set; }

        [System.ComponentModel.Category("Azure Storage")]
        public string Path
        {
            get
            {
                return path_;
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    path_ = "/";
                else if (!value.StartsWith("/"))
                    path_ = "/" + value;
                else
                    path_ = value;
            }
        }

        #endregion Custom Generated Properties

        #region ConnectionUri Members

        /// <summary>
        /// Getter and Setter for the Uri
        /// </summary>
        public override Uri Uri
        {
            get
            {
                StringBuilder uri = new StringBuilder();
                StringBuilder query = new StringBuilder();

                // Format URI Absolute Path

                uri.AppendFormat("{0}://{1}{2}"
                    , AzureStorageAdapter.SCHEME
                    , this.AccountName
                    , this.Path
                    );

                // Format URI Query String

                if (UseDevelopmentStorage)
                    query.AppendFormat("&UseDevelopmentStorage=True");

                uri.AppendFormat("?{0}", query.Length == 0 ? String.Empty : query.Remove(0, 1).ToString());

                return new Uri(uri.ToString());
            }

            set
            {
                if (value.Scheme.CompareTo(AzureStorageAdapter.SCHEME) != 0)
                    throw new ArgumentException(String.Format(Resources.Err_Invalid_Uri_Scheme, value.Scheme));

                if (String.IsNullOrEmpty(value.AbsolutePath))
                    throw new ArgumentException(String.Format(Resources.Err_Invalid_Uri, value, SampleUriString));

                System.Diagnostics.Debug.Assert(value.Scheme.CompareTo(AzureStorageAdapter.SCHEME) == 0);
                System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(value.AbsolutePath));

                this.AccountName = value.Host;
                this.Path = value.AbsolutePath;

                if (!String.IsNullOrEmpty(value.Query))
                    UseDevelopmentStorage =
                        String.IsNullOrEmpty(value.GetQueryStringValue("UseDevelopmentStorage")) ? false :
                        Boolean.Parse(value.GetQueryStringValue("UseDevelopmentStorage"))
                        ;
            }
        }

        #endregion ConnectionUri Members

        public override string SampleUriString
        {
            get
            {
                return String.Format("{0}://accountname/path?useDevelopmentStorage=true"
                     , AzureStorageAdapter.SCHEME
                     );
            }
        }
    }
}

namespace System
{
    public static class UriExtensions
    {
        public static string GetQueryStringValue(this Uri uri, string key)
        {
            string[] query = 
                (uri.Query.StartsWith("?") ? uri.Query.Substring(1) : uri.Query)
                    .ToLowerInvariant()
                    .Split(new char[] { '&' })
                    ;

            key = key.ToLowerInvariant();

            foreach (string item in query)
            {
                string[] pair = item.Split(new char[] { '=' });
                if (pair.Length == 1 && pair[0].CompareTo(key) == 0)
                    return "true";
                else if (pair.Length == 2 && pair[0].CompareTo(key) == 0)
                    return pair[1];
            }

            return String.Empty;
        }
    }
}
